﻿using System;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;

//using Microsoft.SharePoint;
//using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
using Microsoft.SharePoint.Utilities;

//using System.Web;
using System.Data;
using System.Collections;
using System.Collections.Generic;
//using System.Drawing;
using System.Text;


namespace TreeViewWebPartsForDocLib2010.VisualWebPart1
{
    [ToolboxItemAttribute(false)]
    public class VisualWebPart1 : System.Web.UI.WebControls.WebParts.WebPart
    {
        // このパスは、視覚的 Web パーツ プロジェクト アイテムを変更すると Visual Studio で自動的に更新される場合があります。
        private const string _ascxPath = @"~/_CONTROLTEMPLATES/TreeViewWebPartsForDocLib2010/VisualWebPart1/VisualWebPart1UserControl.ascx";

        /*
        protected override void CreateChildControls()
        {
            Control control = Page.LoadControl(_ascxPath);
            Controls.Add(control);
        }
        */

        private string _RootSiteUrl = "";

        private HttpRequest HttpReq
        {
            get
            {
                return HttpContext.Current.Request;
            }
        }

        private HttpResponse HttpRes
        {
            get
            {
                return HttpContext.Current.Response;
            }
        }

        private string RootSiteUrl
        {
            get
            {
                if (this._RootSiteUrl.Trim() == "")
                {
                    string schemeStr = this.HttpReq.Url.Scheme;
                    string authorityStr = this.HttpReq.Url.Authority;

                    this._RootSiteUrl = schemeStr + "://" + authorityStr;
                }
                return this._RootSiteUrl;
            }
        }

        private string RootFolder
        {
            get
            {
                string rootFolder = "";

                if (this.HttpReq.QueryString.HasKeys() == false) return rootFolder;

                bool isExist = false;
                foreach (string key in this.HttpReq.QueryString.AllKeys)
                {
                    if (key == "RootFolder")
                    {
                        isExist = true;
                        break;
                    }
                }
                if (isExist)
                {
                    rootFolder = this.HttpReq.QueryString["RootFolder"];
                }

                return rootFolder;
            }
        }

        private Unit TreeViewWitdth
        {
            get
            {
                Unit treeViewWidth = new Unit("300px");

                if (this.HttpReq.Cookies != null)
                {
                    HttpCookie ck = new HttpCookie("TreeViewWidth");
                    if (this.HttpReq.Cookies["TreeViewWidth"] == null)
                    {
                        if (this.HttpReq.QueryString["TreeViewWidth"] == "left")
                        {
                            treeViewWidth = Unit.Parse((treeViewWidth.Value - 50 < 1 ? 1 : treeViewWidth.Value - 50).ToString() + "px");
                        }
                        else if (this.HttpReq.QueryString["TreeViewWidth"] == "right")
                        {
                            treeViewWidth = Unit.Parse((treeViewWidth.Value + 50).ToString() + "px");
                        }
                    }
                    else
                    {
                        treeViewWidth = Unit.Parse(this.HttpReq.Cookies["TreeViewWidth"].Value);
                        if (this.HttpReq.QueryString["TreeViewWidth"] == "left")
                        {
                            treeViewWidth = Unit.Parse((treeViewWidth.Value - 50 < 1 ? 1 : treeViewWidth.Value - 50).ToString() + "px");
                        }
                        else if (this.HttpReq.QueryString["TreeViewWidth"] == "right")
                        {
                            treeViewWidth = Unit.Parse((treeViewWidth.Value + 50).ToString() + "px");
                        }
                    }
                    ck.Value = treeViewWidth.Value.ToString() + "px";
                    this.HttpRes.Cookies.Add(ck);
                }

                return treeViewWidth;
            }
        }

        private string PostUrl
        {
            get
            {
                string postUrl = this.HttpReq.Url.AbsoluteUri;

                if (this.HttpReq.QueryString.HasKeys() == false)
                {
                    return postUrl;
                }

                bool isExist = false;
                foreach (string key in this.HttpReq.QueryString.AllKeys)
                {
                    if (key == "TreeViewWidth")
                    {
                        isExist = true;
                        break;
                    }
                }
                if (isExist)
                {
                    if (postUrl.Contains("?TreeViewWidth=left"))
                    {
                        postUrl = postUrl.Replace("?TreeViewWidth=left", "");
                    }
                    else if (postUrl.Contains("?TreeViewWidth=left&"))
                    {
                        postUrl = postUrl.Replace("?TreeViewWidth=left&", "?");
                    }
                    else if (postUrl.Contains("&TreeViewWidth=left"))
                    {
                        postUrl = postUrl.Replace("&TreeViewWidth=left", "");
                    }
                    else if (postUrl.Contains("&TreeViewWidth=left&"))
                    {
                        postUrl = postUrl.Replace("&TreeViewWidth=left&", "&");
                    }
                    else if (postUrl.Contains("?TreeViewWidth=right"))
                    {
                        postUrl = postUrl.Replace("?TreeViewWidth=right", "");
                    }
                    else if (postUrl.Contains("?TreeViewWidth=right&"))
                    {
                        postUrl = postUrl.Replace("?TreeViewWidth=right&", "?");
                    }
                    else if (postUrl.Contains("&TreeViewWidth=right"))
                    {
                        postUrl = postUrl.Replace("&TreeViewWidth=right", "");
                    }
                    else if (postUrl.Contains("&TreeViewWidth=right&"))
                    {
                        postUrl = postUrl.Replace("&TreeViewWidth=right&", "&");
                    }
                }

                return postUrl;
            }
        }

        protected override void CreateChildControls()
        {
            base.CreateChildControls();

            TreeNode objRootNode = null;
            SPList objSPList = null;
            SPFolder objSPFolder = null;
            Unit treeViewWidth = this.TreeViewWitdth;

            //Guid siteId = SPContext.Current.Site.ID;
            //Guid webId = SPContext.Current.Web.ID;

            // コントロールにバインドするデータの生成
            string url = this.HttpReq.Url.AbsoluteUri;
            string strRootFolderUrl = this.RootFolder;
            if (SPContext.Current.List == null)
            {
                this.WriteError("ドキュメントライブラリではありません。描画に失敗しました。");
                return;
            }

            try
            {
                Guid ListId = SPContext.Current.List.ID;
                SPWeb web = SPContext.Current.Web;

                objSPList = web.Lists[ListId];

                // ドキュメントライブラリでない場合は、エラーとする
                if (objSPList.BaseType != SPBaseType.DocumentLibrary)
                {
                    this.WriteError("ドキュメントライブラリではありません。描画に失敗しました。");
                    return;
                }

                // SPFolderを取得する
                if (strRootFolderUrl == null)
                {
                    objSPFolder = objSPList.RootFolder;
                }
                else
                {
                    objSPFolder = web.GetFolder(strRootFolderUrl);
                }

                // ツリービューを生成する
                ViewToolBar objViewToolBar = new ViewToolBar();
                this.Controls.Add(objViewToolBar);

                // 矢印ボタンのポストバックURLを取得する
                string postUrl = this.PostUrl;
                if (postUrl.Contains("?"))
                {
                    postUrl += "&";
                }
                else
                {
                    postUrl += "?";
                }

                // 左矢印イメージボタンの作成
                ImageButton imgArrowLeft = new ImageButton();
                imgArrowLeft.ImageUrl = "/_layouts/images/hl_arrow_inactive_hh.gif";
                imgArrowLeft.PostBackUrl = postUrl + "TreeViewWidth=left";
                objViewToolBar.Controls.Add(imgArrowLeft);

                // 右矢印イメージボタンの作成
                ImageButton imgArrowRight = new ImageButton();
                imgArrowRight.ImageUrl = "/_layouts/images/hr_arrow_inactive_hh.gif";
                imgArrowRight.PostBackUrl = postUrl + "TreeViewWidth=right";
                objViewToolBar.Controls.Add(imgArrowRight);

                // ツリービューに表示するルートノードの作成
                objRootNode = this.CreateRootNode(objSPList);
                objRootNode.ChildNodes.Add(new TreeNode("dummy"));
            }
            catch (Exception ex)
            {
                this.WriteError("描画に失敗しました。" + ex.Message);
                return;
            }

            // コントロールの生成
            Table table = new Table();
            table.CellSpacing = 0;
            {
                TableRow row1 = new TableRow();
                row1.VerticalAlign = VerticalAlign.Top;
                {
                    Microsoft.SharePoint.WebControls.ListView objListView = new Microsoft.SharePoint.WebControls.ListView();
                    objListView.ID = "listView";
                    objListView.ListId = objSPList.ID.ToString();
                    objListView.ViewId = objSPList.DefaultView.ID.ToString();

                    TableCell cell_1 = new TableCell();
                    cell_1.BorderStyle = BorderStyle.Solid;
                    cell_1.BorderWidth = Unit.Parse("1px");
                    cell_1.ColumnSpan = 3;

                    Panel objPanel = new Panel();
                    objPanel.ID = "leftPanel";
                    objPanel.Width = treeViewWidth;
                    objPanel.ScrollBars = ScrollBars.Auto;
                    objPanel.Height = Unit.Pixel(800);
                    objPanel.BorderStyle = System.Web.UI.WebControls.BorderStyle.None;

                    TreeView objTreeView = new TreeView();
                    objTreeView.ID = "_TreeView";
                    objTreeView.ExpandDepth = 0;
                    objTreeView.ImageSet = TreeViewImageSet.Custom;
                    objTreeView.TreeNodeExpanded += new TreeNodeEventHandler(objTreeView_TreeNodeExpanded);
                    objTreeView.TreeNodeCollapsed += new TreeNodeEventHandler(objTreeView_TreeNodeCollapsed);
                    objTreeView.Height = Unit.Pixel(800 - 50);
                    objTreeView.ShowExpandCollapse = true;
                    objTreeView.BorderStyle = System.Web.UI.WebControls.BorderStyle.None;

                    if (objRootNode != null)
                    {
                        objTreeView.Nodes.Add(objRootNode);
                    }

                    objPanel.Controls.Add(objTreeView);
                    cell_1.Controls.Add(objPanel);

                    TableCell cell_2 = new TableCell();
                    cell_2.ColumnSpan = 3;
                    cell_2.Width = Unit.Parse("100%");

                    cell_2.Controls.Add(objListView);

                    row1.Controls.Add(cell_1);
                    row1.Controls.Add(cell_2);
                }
                table.Rows.Add(row1);
                this.Controls.Add(table);

                // 現在ページまでのノードを展開する
                this.ExpandNode(objSPFolder, objRootNode);
            }
        }

        private TreeNode CreateRootNode(SPList objSPList)
        {
            TreeNode objRootNode = null;

            objRootNode = new TreeNode(
                objSPList.Title +
                " (" + objSPList.ItemCount.ToString() + " Items, " +
                objSPList.Folders.Count.ToString() + " Folders)",
                objSPList.RootFolder.UniqueId.ToString());
            objRootNode.NavigateUrl = this.RootSiteUrl + objSPList.RootFolder.ServerRelativeUrl;
            objRootNode.SelectAction = TreeNodeSelectAction.Expand;
            objRootNode.ImageUrl = objSPList.ImageUrl;
            objRootNode.ToolTip = objSPList.Title;
            if (objSPList.RootFolder.SubFolders.Count > 0)
            {
                objRootNode.ChildNodes.Add(new TreeNode("dummy"));
            }

            return objRootNode;
        }

        private void ExpandNode(SPFolder objSPFolder, TreeNode objRootNode)
        {
            string[] paths = objSPFolder.Url.Split('/');
            int cnt = 0;
            TreeNode current = objRootNode;
            foreach (string path in paths)
            {
                if (cnt == 0)
                {
                    cnt++;
                    continue;
                }

                current.Expand();
                foreach (TreeNode n in current.ChildNodes)
                {
                    current = this.GetNextNode(n, path);
                    if (current != null)
                    {
                        break;
                    }
                }
                if (current == null)
                {
                    break;
                }
            }
        }

        private TreeNode GetNextNode(TreeNode node, string path)
        {
            TreeNode child = null;

            if (node.ToolTip == path)
            {
                child = node;
            }

            return child;
        }

        private void WriteError(string msg)
        {
            Label ErrorLabel = new Label();

            ErrorLabel.Text = msg;
            //ErrorLabel.BackColor = //Color.Red;
            //ErrorLabel.ForeColor = //Color.Yellow;
            this.Controls.Add(ErrorLabel);

            return;
        }

        private TreeNode CreateNode(SPFolder folder)
        {
            SPWeb web = SPContext.Current.Web;
            SPList list = folder.ParentWeb.Lists[folder.ParentListId];

            TreeNode subNode = new TreeNode();
            if (folder.SubFolders.Count == 0)
            {
                subNode.Text = folder.Name + " (" + folder.Files.Count.ToString() + " Files)";
            }
            else
            {
                subNode.Text = folder.Name + " (" + folder.Files.Count.ToString() + " Files, "
                    + folder.SubFolders.Count.ToString() + " Folders)";
                subNode.ChildNodes.Add(new TreeNode("dummy"));
            }
            subNode.ImageUrl = "_layouts/images/folder.gif";
            subNode.Value = folder.UniqueId.ToString();
            subNode.NavigateUrl =
                this.RootSiteUrl + list.RootFolder.ServerRelativeUrl + "/Forms/AllItems.aspx?RootFolder=" +
                HttpUtility.UrlEncode(folder.ServerRelativeUrl, Encoding.UTF8).Replace("+", "%20") +
                "&FolderCTID=&View=" +
                HttpUtility.UrlEncode("{" + list.DefaultView.ID.ToString().ToUpper() + "}", Encoding.UTF8).Replace("-", "%2d");
            subNode.ToolTip = folder.Name;
            subNode.SelectAction = TreeNodeSelectAction.SelectExpand;

            return subNode;
        }

        void objTreeView_TreeNodeCollapsed(object sender, TreeNodeEventArgs e)
        {
            TreeNode node = e.Node;
            node.ChildNodes.Clear();
            node.ChildNodes.Add(new TreeNode("dummy"));
        }

        void objTreeView_TreeNodeExpanded(object sender, TreeNodeEventArgs e)
        {
            TreeNode node = e.Node;
            node.ChildNodes.Clear();

            SPWeb web = SPContext.Current.Web;

            SPFolderCollection folders = null;
            SPFolder nodeFolder = null;
            if (node.Depth == 0)
            {
                // ルートフォルダーの場合
                SPList list = web.Lists[SPContext.Current.ListId];
                folders = list.RootFolder.SubFolders;
                nodeFolder = list.RootFolder;
            }
            else
            {
                // サブフォルダの場合
                SPFolder item = web.GetFolder(new Guid(node.Value));
                folders = item.SubFolders;
                nodeFolder = item;
            }

            // ツリーにフォルダを追加する
            // ※Formsフォルダは除外する
            List<string> strfolders = new List<string>();
            foreach (SPFolder folder in folders)
            {
                if (folder.Name == "Forms") continue;
                strfolders.Add(web.Url + @"/" + folder.Url);
            }
            strfolders.Sort();

            foreach (string folder in strfolders)
            {
                TreeNode subNode = this.CreateNode(folders[folder]);
                node.ChildNodes.Add(subNode);
            }
        }
    }
}
